<?php

declare(strict_types=1);

namespace app\eslib;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

/**
 * JSON Web Tokens 助手类
 * @version 1.0.0
 * 依赖: composer require firebase/php-jwt
 * 仓库: https://github.com/firebase/php-jwt
 */
class EsJwt
{

    public static function encodeJWT(array $data, $option = [], string $key = 'FpwuzjkDI+17t5', string $algorithm = 'HS256'): array
    {
        // 载荷（存放有效信息的地方）
        $payload = [
            // iss: issuer。jwt签发者（网址或IP，例如：http://example.com）
            'iss' => 'http://example.org',
            // aud: audience。受众，接收jwt的一方（网址或IP，例如：http://example.com）
            'aud' => 'http://example.org',
            // iat: Issued At。jwt的签发时间
            'iat' => time(),
            // nbf: Not Before。定义在什么时间之前，该 jwt 是不可用的（这个时间之前是无效的，一般来讲会设置成签发的时间，例如：strtotime('10 hours')）。
            'nbf' => time(),
            // expiration time 过期时间
            'exp' => strtotime('1 days'),
            // 携带数据
            'data' => $data,
        ];
        if ($option) {
            $payload = array_merge($payload, $option);
        }
        return [
            JWT::encode($payload, $key, $algorithm),
            $payload
        ];
    }
    public static function decodeJWT(string $jwt, $key = 'FpwuzjkDI+17t5', $algorithm = 'HS256'): array
    {
        // leeway 余量时间: 虽然同步时间过后问题已经消失，但是服务器之间仍然可能会产生微小的时间差，可以通过增加 leeway 来覆盖这种偶发的场景，但是 leeway 也不能无限加长，时间太长会造成安全性下降。
        // JWT::$leeway = strtotime('1 days'); // 校正服务器时间（延迟8小时）
        try {
            $payload = JWT::decode($jwt, new Key($key, $algorithm));
            if ($payload->nbf > time()) {
                return EsUtils::stdMessage(false, 'Token 不可用');
            }
            if ($payload->exp < time()) {
                return EsUtils::stdMessage(false, 'Token 已过期');
            }
            return EsUtils::stdMessage(true, '', $payload->data);
        } catch (\Exception $ex) {
            return EsUtils::stdMessage(false, $ex->getMessage());
        }
    }
}
